`timescale 1ns / 1ps

module divider(
    input  [31:0] dividend,    // 被除数
    input  [31:0] divisor,     // 除数
    output [31:0] quotient,    // 商
    output [31:0] remainder    // 余数
);

    reg [31:0] temp_quotient;
    reg [31:0] current_remainder;
    
    // 提取符号位
    wire dividend_sign = dividend[31];
    wire divisor_sign = divisor[31];
    wire result_sign = dividend_sign ^ divisor_sign; //最终结果符号：两个操作数符号相同为正，不同为负
    
    // 计算操作数的绝对值
    wire [31:0] abs_dividend = dividend_sign ? (~dividend + 1) : dividend;
    wire [31:0] abs_divisor = divisor_sign ? (~divisor + 1) : divisor;
    
    reg [31:0] remainder_reg; //用于存储余数
    reg [31:0] dividend_reg;  //用于存储被除数
    reg [31:0] divisor_reg;   //用于存储除数
    integer i;
    
    always @(*) begin
        temp_quotient = 0;
        if (abs_divisor != 0) begin
            remainder_reg = 32'b0;
            dividend_reg = abs_dividend;
            divisor_reg = abs_divisor;
            
            for (i = 31; i >= 0; i = i - 1) begin
                // 余数左移，并将被除数的最高位移入
                remainder_reg = {remainder_reg[30:0], dividend_reg[31]};
                dividend_reg = {dividend_reg[30:0], 1'b0};
                
                // 如果当前余数为非负数，执行减法
                if (!remainder_reg[31]) begin
                    remainder_reg = remainder_reg - divisor_reg;
                end 
                // 如果当前余数为负数，执行加法
                else begin
                    remainder_reg = remainder_reg + divisor_reg;
                end
                
                // 根据运算后的余数符号设置商位
                temp_quotient = temp_quotient<<1;
                if (!remainder_reg[31]) begin
                    temp_quotient = temp_quotient | 1'b1;
                end
            end
            
            // 修正：如果余数为负，加回一次除数
            if (remainder_reg[31]) begin
                remainder_reg = remainder_reg + divisor_reg;
            end
            
            current_remainder = remainder_reg;
        end else begin
            temp_quotient = 32'hffffffff;//除数为0时，全1表错
        end
    end
    // 根据符号位确定最终结果
    assign quotient = result_sign ? (~temp_quotient + 1) : temp_quotient;
    assign remainder = dividend_sign ? (~current_remainder + 1) : current_remainder;

endmodule